<template>
  <div>
      <el-form :model="form" :rules="rules" ref="formRef">
        <el-form-item label="语法检测表达式：" :label-width="formLabelWidth" prop="expression">
          <el-input v-model="form.expression" autocomplete="off" placeholder="请输入语法检测表达式" />
        </el-form-item>
        <el-form-item label="规则说明：" :label-width="formLabelWidth" prop="description">
          <el-input v-model="form.description" autocomplete="off" placeholder="请输入规则说明" />
        </el-form-item>
        <el-form-item label="脚本类型：" :label-width="formLabelWidth" prop="script_types">
          <el-select
            v-model="form.script_types"
            multiple
            collapse-tags
            collapse-tags-tooltip
            placeholder="请选择脚本类型"
            @change="handleScriptTypeChange"
          >
            <!-- 全选选项 -->
            <el-option
              key="all"
              :label="isAllSelected ? '取消全选' : '全选'"
              :value="'all'"
            />
            <!-- 普通选项 -->
            <el-option
              v-for="item in scriptOptions"
              :key="item.id"
              :label="item.type"
              :value="item.type"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="动作：" :label-width="formLabelWidth" prop="action">
          <el-select
            v-model="form.action"
            placeholder="请选择动作"
          >
            <el-option
              v-for="item in actionOptions"
              :key="item.id"
              :label="item.type"
              :value="item.type"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="是否启用：" :label-width="formLabelWidth">
          <el-switch v-model="form.status" size="small" />
        </el-form-item>
      </el-form>
      <div class="dialog-footer">
        <el-button @click="cancel()">取消</el-button>
        <el-button type="primary" @click="confirm()">
          提交
        </el-button>
      </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, defineEmits, defineProps, onMounted, defineExpose, computed } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { ElMessage } from 'element-plus'
import { dangerousRuleAdd,getScriptType,getAction,dangerousRuleUpdate } from '@/api/dangerousHostApi'
import { getUserName } from '@/utils/auth';

const formLabelWidth = '140px'
const formRef = ref<FormInstance>()
const form = reactive({
  expression: '',
  description: '',
  script_types: [] as string[],
  action: '',
  creator: getUserName(),
  status: false,   
})

// 计算属性：判断是否已全选
const isAllSelected = computed(() => {
  if (scriptOptions.value.length === 0) return false;
  const allValues = scriptOptions.value.map(item => item.type);
  return allValues.every(value => form.script_types.includes(value));
})

// 处理脚本类型选择变化
const handleScriptTypeChange = (values: string[]) => {
  if (values.includes('all')) {
    // 如果选择了全选
    if (isAllSelected.value) {
      // 如果已经是全选状态，取消全选
      form.script_types = [];
    } else {
      // 如果不是全选状态，选择全部脚本类型
      form.script_types = scriptOptions.value.map(item => item.type);
    }
  }
}
// 表单验证规则
const rules = reactive<FormRules>({
  expression: [
    { required: true, message: '请输入语法检测表达式', trigger: 'blur' },
    { min: 1, max: 200, message: '长度在 1 到 200 个字符', trigger: 'blur' }
  ],
  description: [
    { required: true, message: '请输入规则说明', trigger: 'blur' },
    { min: 1, max: 500, message: '长度在 1 到 500 个字符', trigger: 'blur' }
  ],
  script_types: [
    { required: true, message: '请选择脚本类型', trigger: 'change' },
    { type: 'array', min: 1, message: '至少选择一个脚本类型', trigger: 'change' }
  ],
  action: [
    { required: true, message: '请选择动作', trigger: 'change' }
  ]
})
const scriptOptions = ref([{id: '',type:''}])
const actionOptions = ref([{id: '',type:''}])
// const props = defineProps({
// })
const emit = defineEmits<{
  (e: 'submit', formData: any): void;
  (e: 'close'): void;   
}>();
const props = defineProps({
  data: {
    type: Object,
    required: true,
  },
  isEdit: {
    type: Boolean,
    default: false,
  },
})

const confirm = async () => {
  if (!formRef.value) return;
  
  try {
    await formRef.value.validate();
    
    const formData:any = { ...form };
    formData.script_types = formData.script_types.join(',') as any
    if(props.isEdit) {
      delete formData.creator
      const res = await dangerousRuleUpdate(formData)
      if(res.data.code === 200) {
        // 验证通过，提交表单
        emit('submit', form);
        ElMessage.success('修改成功')
      }else{
        ElMessage.error(res.data.msg)
      }

    }else{
      const res = await dangerousRuleAdd(formData)
      if(res.data.code === 200) {
        // 验证通过，提交表单
        emit('submit', form);
        ElMessage.success('添加成功')
      }else{
        ElMessage.error(res.data.msg)
      }
    }
  } catch (error) {
    
    console.log('表单验证失败:', error);
  }
}
const cancel = () => {
  // 重置表单
  emit('close')
}
const getScriptTypeFun = async () => {
  // 获取脚本类型
  const res = await getScriptType()
  if(res.data.code === 200) {
    scriptOptions.value = res.data.data
  } else{
    ElMessage.error(res.data.msg)
  }

}
const getActionFun = async () => {
  // 获取动作
  const res = await getAction()
  if(res.data.code === 200) {
    actionOptions.value = res.data.data
  }else{
    ElMessage.error(res.data.msg)
  }
}

// 重置表单数据（如果需要的话可以暴露给父组件使用）
const resetForm = () => {
  Object.assign(form, {
    expression: '',
    description: '',
    script_types: [],
    action: '',
    creator: getUserName(),
    status: false,
  });
}

onMounted(() => {
  getScriptTypeFun()
  getActionFun()
  console.log('[ props.isEdit ] >', props.isEdit)
  if(props.isEdit) {
    Object.assign(form, props.data);
  }else{
    resetForm()
  }
})
defineExpose({ resetForm })
</script>

<style lang="scss" scoped>
.dialog-footer {
  text-align: right;
  margin-top: 20px;
  
  .el-button {
    margin-left: 10px;
  }
}

:deep(.el-form-item__label) {
  font-weight: 500;
}

:deep(.el-input__inner),
:deep(.el-select .el-input__inner) {
  border-radius: 4px;
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}
</style>